package com.qdlc.p2p.biz.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.qd.p2p.adapter.AdaptedRequestHandleService;
import com.qd.p2p.adapter.param.QueryBalanceParameter;
import com.qd.p2p.adapter.response.QueryBalanceResponse;
import com.qdlc.p2p.biz.service.AccountCashService;
import com.qdlc.p2p.biz.service.SystemConfigService;
import com.qdlc.p2p.biz.service.TppAccountService;
import com.qdlc.p2p.biz.tpp.TppBaseInterface;
import com.qdlc.p2p.biz.tpp.TppServiceFactory;
import com.qdlc.p2p.biz.tpp.TppSinaServiceImpl;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.exception.TppChinapnrException;
import com.qdlc.p2p.common.util.BigDecimalUtil;
import com.qdlc.p2p.common.util.DateUtil;
import com.qdlc.p2p.common.util.HttpUtil;
import com.qdlc.p2p.common.util.MessageUtil;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.common.model.jpa.QueryParam;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dao.SystemConfigDao;
import com.qdlc.p2p.dal.dao.TppAccountDao;
import com.qdlc.p2p.dal.dao.TppBonusDetailsDao;
import com.qdlc.p2p.dal.dao.TppDao;
import com.qdlc.p2p.dal.dao.TppDifferenceDao;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.dto.SystemConfig;
import com.qdlc.p2p.dal.dto.Tpp;
import com.qdlc.p2p.dal.dto.TppAccount;
import com.qdlc.p2p.dal.dto.TppBonusDetails;
import com.qdlc.p2p.dal.dto.TppDifference;
import com.qdlc.p2p.dal.dto.User;
import com.qdlc.p2p.dal.model.TppAccountModel;
import com.qdlc.p2p.dal.model.TppModel;

/**
 * 第三方托管账户金额业务处理
 *
 * @author ygw
 * @version 2.0
 * @date 2015年11月18日 下午4:26:08
 */
@Service("tppAccountService")
@Transactional
public class TppAccountServiceImpl implements TppAccountService {
    private static Logger logger = Logger.getLogger(TppAccountServiceImpl.class);

    @Resource
    private TppAccountDao tppAccountDao;

    @Resource
    private AccountDao accountDao;

    @Resource
    private TppDao tppDao;

    @Resource
    private TppDifferenceDao tppDifferenceDao;

    @Resource
    private TppBonusDetailsDao tppBonusDetailsDao;

    @Resource
    private AccountCashService accountCashService;

    @Resource
    private SystemConfigDao systemConfigDao;

    @Resource
    private SystemConfigService systemConfigService;
    
    @Resource
    private AdaptedRequestHandleService aRHservice;

    public TppAccount findByUser(long userId) {
        return tppAccountDao.findObjByProperty("user.userId", userId);
    }

    @Override
    public void updateStatus() {
        logger.info("处理新浪对账先更新旧数据为已处理=======");
        // 先更新旧数据为已处理
        tppDifferenceDao.updateStatus();
    }

    @Override
    public void setDifference(User user) {
        TppModel tppModel = new TppModel();
        // 本地账户金额
        Account account = accountDao.findByUserId(user.getUserId());
        // 查询第三方托管账户金额信息
        tppModel.setUser(user);
        TppBaseInterface tppService = new TppSinaServiceImpl();
        // 托管账户金额
        TppAccountModel queryBalance = (TppAccountModel) tppService.tppQueryBalance(tppModel);
        if (null == queryBalance) {
            // 第三方托管账户金额信息未找到！
            logger.error("用户：" + user.getTppUserCustId() + "第三方托管账户金额信息未找到！");
            return;
        }
        double tppTotalMoney = Double.parseDouble(queryBalance.getTotalMoney());// 托管余额/基金份额
        double tppUseMoney = Double.parseDouble(queryBalance.getUserMoney());// 托管可用余额/基金份额
        double tppNoUseMoney = Double.parseDouble(queryBalance.getNoMoney());// 托管冻结总额

        // 用户本地可用余额
        double useMoney = account.getUseMoney();
        // 获取该用户待付手续费
        double manageFee = accountCashService.getWithdrawCashManageFeeByUserId(user.getUserId());
        double realUseMoney = BigDecimalUtil.add(useMoney, manageFee);// 用户本地可用余额+待付手续费
        // 可用差额 = 托管可用余额 - 本地可用余额
        double differenceUse = BigDecimalUtil.decimal(BigDecimalUtil.sub(tppUseMoney, useMoney), 2);
        // 用户本地可用余额+待付手续费已经等于了托管可用余额：不处理
        if (realUseMoney != tppUseMoney && differenceUse != 0) {

            // 排除调度任务未成功
            Tpp tpp = tppDao.getTppByCustId(user.getTppUserCustId(), user.getTppUserCustId(), 1);// 不等于1 （status：0：未处理，1：成功，2：失败）
            // 排除存钱罐收益未更新
            QueryParam param = QueryParam.getInstance();
            param.addParam("user", user).addParam("status", 0);
            List<TppBonusDetails> bonusDetails = tppBonusDetailsDao.findByCriteria(param);// 所有未更新列表
            if (tpp == null && bonusDetails.size() <= 0) {
                // 插入用户托管资金差额表
                // 余额差额 = 托管余额 - 本地余额
                double differenceTotal = BigDecimalUtil.decimal(BigDecimalUtil.sub(tppTotalMoney, account.getTotal()), 2);
                // 总冻结差额 = 托管冻结总额 - 本地冻结总额
                double differenceUseNo = BigDecimalUtil.decimal(BigDecimalUtil.sub(tppNoUseMoney, account.getNoUseMoney()), 2);
                TppDifference tppDifference = tppDifferenceDao.findObjByProperty("user.userId", user.getUserId());
                if (tppDifference == null) {
                    tppDifference = new TppDifference(user);
                }
                tppDifference.setTotal(account.getTotal());// 账户余额
                tppDifference.setTppTotal(tppTotalMoney);// 托管账户余额
                tppDifference.setDifferenceTotal(differenceTotal);// 余额差额
                tppDifference.setUseMoney(account.getUseMoney());// 可用余额
                tppDifference.setTppUseMoney(tppUseMoney);// 托管可用余额
                tppDifference.setDifferenceUse(differenceUse);// 可用余额差额
                tppDifference.setNoUseMoney(account.getNoUseMoney());// 冻结总额
                tppDifference.setTppNoUseMoney(tppNoUseMoney);// 托管冻结总额
                tppDifference.setDifferenceNoUse(differenceUseNo);// 总冻结差额
                tppDifference.setAddTime(DateUtil.getNow());// 添加时间
                tppDifference.setStatus(0); // 处理状态 0：未处理 1：已处理
                tppDifferenceDao.save(tppDifference);
            }
        }
    }
    
    @Override
    public void setBaofooDifference(User user) {
        // 本地账户金额
        Account account = accountDao.findByUserId(user.getUserId());
        // 查询第三方托管账户金额信息
        QueryBalanceParameter parameter = new QueryBalanceParameter();
        String tppUserCustId = user.getTppUserCustId();
		parameter.setPlatformUserId(tppUserCustId);
		QueryBalanceResponse queryBalance = aRHservice.queryBalance(parameter);
        if (null == queryBalance || !queryBalance.isSuccess()) {
            // 第三方托管账户金额信息未找到！
            logger.error("用户：" + user.getTppUserCustId() + "第三方托管账户金额信息未找到！");
            return;
        }
        double tppTotalMoney = account.getTotal();// 托管总额(默认本地)
        double tppUseMoney = queryBalance.getBalance();// 托管可用余额
        double tppNoUseMoney = account.getNoUseMoney();// 托管冻结总额(默认本地)

        // 用户本地可用余额
        double useMoney = account.getUseMoney();
        // 可用差额 = 托管可用余额 - 本地可用余额
        double differenceUse = BigDecimalUtil.decimal(BigDecimalUtil.sub(tppUseMoney, useMoney), 2);
        // 用户本地可用余额+待付手续费已经等于了托管可用余额：不处理
        if (useMoney != tppUseMoney && differenceUse != 0) {
            // 排除调度任务未成功
            Tpp tpp = tppDao.getTppByCustId(tppUserCustId, tppUserCustId, 1);// 不等于1 （status：0：未处理，1：成功，2：失败）
            if (tpp == null) {
                // 插入用户托管资金差额表
            	 // 余额差额 = 托管余额 - 本地余额
                double differenceTotal = BigDecimalUtil.decimal(BigDecimalUtil.sub(tppTotalMoney, account.getTotal()), 2);
                // 总冻结差额 = 托管冻结总额 - 本地冻结总额
                double differenceUseNo = BigDecimalUtil.decimal(BigDecimalUtil.sub(tppNoUseMoney, account.getNoUseMoney()), 2);
                TppDifference tppDifference = tppDifferenceDao.findObjByProperty("user.userId", user.getUserId());
                if (tppDifference == null) {
                    tppDifference = new TppDifference(user);
                }
                tppDifference.setTotal(account.getTotal());// 账户余额
                tppDifference.setTppTotal(tppTotalMoney);// 托管账户余额
                tppDifference.setDifferenceTotal(differenceTotal);// 余额差额
                tppDifference.setUseMoney(account.getUseMoney());// 可用余额
                tppDifference.setTppUseMoney(tppUseMoney);// 托管可用余额
                tppDifference.setDifferenceUse(differenceUse);// 可用余额差额
                tppDifference.setNoUseMoney(account.getNoUseMoney());// 冻结总额
                tppDifference.setTppNoUseMoney(tppNoUseMoney);// 托管冻结总额
                tppDifference.setDifferenceNoUse(differenceUseNo);// 总冻结差额
                tppDifference.setAddTime(DateUtil.getNow());// 添加时间
                tppDifference.setStatus(0); // 处理状态 0：未处理 1：已处理
                tppDifferenceDao.save(tppDifference);
            }
        }
    }

    @Override
    public void setQueryFundYield() {
        // 查询存钱罐基金收益率
        logger.info("更新存钱罐基金收益率JOB =======");
        TppModel tppModel = new TppModel();
        TppBaseInterface tppService = TppServiceFactory.newIntance();
        TppAccountModel queryFundYield = (TppAccountModel) tppService.tppQueryFundYield(tppModel);
        if (null == queryFundYield) {
            // 信息未找到！
            throw new TppChinapnrException(MessageUtil.getMessage("MF103006003"));
        }
        SystemConfig sc = systemConfigDao.findObjByProperty("nid", "con_yield_list");
        sc.setValue(queryFundYield.getYieldList());
        systemConfigDao.update(sc);
        Global.setTransfer("yield_list", queryFundYield.getYieldList());
        // 缓存清理
        systemConfigService.clean();
        // 前台路径
        String web_url = SystemConfigHelper.getValue(SystemConfigHelper.Nid.WEB_URL);
        String url = web_url + "/system/clean.html";
        // 前台缓存清理
        if (web_url.startsWith("https")) {
            HttpUtil.getHttpsResponse(url);
        } else {
            HttpUtil.getHttpResponse(url);
        }
    }
}
